package com.fast.fast.common.feign.config;

import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.fastjson.JSONObject;
import com.fast.fast.common.base.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;

import javax.servlet.http.HttpServletRequest;

/**
 * Sentinel配置类
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 **/
@Slf4j
@AutoConfiguration
public class SentinelConfig {

    private static final String MSG = "服务器正忙,请稍后再试";

    /**
     * 限流、熔断统一处理类(web mvc)
     */
    @AutoConfiguration
    @ConditionalOnClass(HttpServletRequest.class)
    public static class WebmvcHandler {
        @Bean
        public BlockExceptionHandler webmvcBlockExceptionHandler() {
            return (request, response, e) -> {
                log.error(MSG, e);
                Result<?> result = Result.error(MSG, HttpStatus.TOO_MANY_REQUESTS.value());
                response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
                response.getWriter().print(JSONObject.toJSONString(result));
            };
        }
    }

    /**
     * 限流、熔断统一处理类(web flux)
     */
    @AutoConfiguration
    @ConditionalOnClass(ServerResponse.class)
    public static class WebfluxHandler {
        @Bean
        public BlockRequestHandler webfluxBlockExceptionHandler() {
            return (exchange, throwable) -> {
                log.error(MSG, throwable);
                return ServerResponse
                        .status(HttpStatus.TOO_MANY_REQUESTS)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(Result.error(MSG, HttpStatus.TOO_MANY_REQUESTS.value())));
            };

        }
    }
}
